#ifndef SEGMENTTREELIST_H
#define SEGMENTTREELIST_H

/**
 * \file	segmenttreelist.h
 * \brief	Declaration de la classe SegmentTreeList representant une liste de noeuds d'arbre.
 */

#include "segmenttree.h"
#include "boundingbox.h"

class SegmentTreeList
{
	/*!
	 * \class SegmentTreeList
	 * \brief Classe représentant une liste de noeuds d'arbre.
	 * 
	 * Classe représentant une liste de noeuds d'arbre.
	 * Donne des outils plus elabores et plus specifiques que les outils standard des listes en c++ (notamment la methode contains).
	 *
	 */
	private :
		list<SegmentTree*>		nodes;				/*! Liste de noeuds.*/
	
	public:
		/*!
		*  \brief Default constructor of the SegmentTreeList class.
		*
		*  Default constructor of the SegmentTreeList class : Every attributes are initialized to 0 (int,float,double,...) NULL (pointers) or are cleared (lists, stacks, ...).
		*/
	    SegmentTreeList();
		
		/*!
		*  \brief Copy constructor of the SegmentTreeList class.
		*
		*  Copy constructor of the SegmentTreeList class.
		*/
		SegmentTreeList( const SegmentTreeList& _list );
		
		/*!
		*  \brief Destructor of the SegmentTreeList class.
		*
		*  Destructor of the SegmentTreeList class.
		*/
		~SegmentTreeList();
		
		/*!
		*  \brief Affectation operator of the SegmentTreeList class.
		*
		*  Affectation operator of the SegmentTreeList class.
		*/
		SegmentTreeList& operator= ( const SegmentTreeList& _list );
		
		/*!
		*  \brief Addition operator of the SegmentTreeList class.
		*
		*  Addition operator of the SegmentTreeList class :
		*  The result is a list containing all the initial elements plus all the elements of the _list list. The result won't contain any doubloon.
		*/
		SegmentTreeList& operator+ ( const SegmentTreeList& _list );
		
		/*!
		*  \brief Addition operator of the SegmentTreeList class.
		*
		*  Addition operator of the SegmentTreeList class :
		*  The result is a list containing all the initial elements plus all the elements of the _list list. The result won't contain any doubloon.
		*/
		SegmentTreeList& operator+= ( const SegmentTreeList& _list );
		
		/*!
		*  \brief Getter of the SegmentTreeList class.
		*
		*  Getter of the SegmentTreeList class.
		*
		*  \return (list<SegmentTree*>) Returns the nodes list of the segmentTreeList.
		*/
		list<SegmentTree*> getNodes ();
		
		/*!
		*  \brief Getter of the SegmentTreeList class.
		*
		*  Getter of the SegmentTreeList class.
		*
		*  \return (list<SegmentTree*>::iterator) Returns the begining iterator of the list.
		*/
		list<SegmentTree*>::iterator getBegin ();
		
		/*!
		*  \brief Getter of the SegmentTreeList class.
		*
		*  Getter of the SegmentTreeList class.
		*
		*  \return (list<SegmentTree*>::iterator) Returns the ending iterator of the list.
		*/
		list<SegmentTree*>::iterator getEnd ();
		
		/*!
		*  \brief Getter of the SegmentTreeList class.
		*
		*  Getter of the SegmentTreeList class.
		*
		*  \return (SegmentTree*) Returns the first element of the list.
		*/
		SegmentTree* getFirst ();
		
		/*!
		*  \brief Setter of the SegmentTreeList class.
		*
		*  Setter of the SegmentTreeList class.
		*
		*  \param nodes : List to attribuate to the SegmentTreeList.
		*
		*  \return (void)
		*/
		void setNodes ( list<SegmentTree*> _nodes );
		
		/*!
		*  \brief Clears the list.
		*
		*  Clears the list.
		*
		*  \return (void)
		*/
		void clear ();
		
		/*!
		*  \brief Indicates if a list is empty.
		*
		*  Indicates if a list is empty.
		*
		*  \return (bool) Returns true if the list is empty, false else.
		*/
		bool empty ();
		
		/*!
		*  \brief Looks if a specific node is contained by the list.
		*
		*  Looks if a specific node is contained by the list.
		*
		*  \param _node : Node we want to search in the list.
		*
		*  \return (bool) Returns true if the node has been found, false else.
		*/
		bool contains ( SegmentTree* _node );
		
		/*!
		*  \brief Adds a node to the list.
		*
		*  Adds a node to the list.
		*
		*  \param _node : Node we want to add to the list.
		*
		*  \return (void)
		*/
		void addNode ( SegmentTree* _node );
		
		/*!
		*  \brief Creates a list containing all the node in the target matched by the reference node given in parameter according an intersection criteria.
		*
		*  Creates a list containing all the node in the target matched by the reference node given in parameter according to an intersection criteria.
		*
		*  \param _reference : Node taken as the reference for the computation.
		*  \param _target : Tree containing the segments we want to match the node's segment.
		*
		*  \return (void)
		*/
		void getMatchBy_Intersection ( SegmentTree* _reference, SegmentTree* _target );
		
		/*!
		*  \brief Creates a list containing all the node in the target matched by the reference node given in parameter according to the distance criteria.
		*
		*  Creates a list containing all the node in the target matched by the reference node given in parameter according to the distance criteria.
		*  The distance choosen here is simply the number of edge separating two vertices in the mesh.
		*
		*  \param _reference : Node taken as the reference for the computation.
		*  \param _target : Tree containing the segments we want to match the node's segment.
		*  \param _mesh : Mesh supporting the target segments ( only useful to know the number of vertices in order to create a mark array for the BFS ).
		*  \param _distMax : Distance maximum to considerate two segments as neighbours.
		*
		*  \return (void)
		*/
		void getMatchBy_Distance ( SegmentTree* _reference, SegmentTree* _target, Mesh* _mesh, int _distMax );
		
		/*!
		*  \brief Creates a list containing all the node in the target matched by the reference node given in parameter according the "equal depth" criteria.
		*
		*  Creates a list containing all the node in the target matched by the reference node given in parameter according to the "equal depth" criteria.
		*
		*  \param _reference : Node taken as the reference for the computation.
		*  \param _target : Tree containing the segments we want to match the node's segment.
		*  \param _distMax : Distance maximum to considerate two segments as neighbours.
		*
		*  \return (void)
		*/
		void getMatchBy_Depth ( SegmentTree* _reference, SegmentTree* _target, int _distMax  );
		
		/*!
		*  \brief Creates a list containing all the node in the target matched by the reference node given in parameter according an area similarity criteria.
		*
		*  Creates a list containing all the node in the target matched by the reference node given in parameter according an area similarity criteria.
		*  Note that the areas of the different nodes are computed as a per centage of their attached meshes.
		*
		*  \todo Pour alleger les calculs les aires des segments pourraient etre directement stockees dans les segments.
		*
		*  \param _reference : Node taken as the reference for the computation.
		*  \param _refMesh : Mesh supporting the reference segment.
		*  \param _refMeshArea : Area of the mesh supporting the reference segment.
		*  \param _target : Tree containing the segments we want to match the node's segment.
		*  \param _targetMesh : Mesh supporting the target segments.
		*  \param _targetMeshArea : Area of the mesh supporting the target segments.
		*  \param _distMax : Distance maximum to considerate two segments as neighbours.
		*
		*  \return (void)
		*/
		void getMatchBy_Areas ( SegmentTree* _reference, Mesh* _refMesh, double _refMeshArea, SegmentTree* _target, Mesh* _targetMesh, double _targetMeshArea, double _distMax  );
		
		/*!
		*  \brief Creates a list containing all the node in the target matched by the reference node given in parameter according to a similarity on the bounding boxes.
		*
		*  Creates a list containing all the node in the target matched by the reference node given in parameter according to a similarity on the bounding boxes :
		*  If the difference between the x coordinate of the bot point of the bounding box of the reference node and the bot point of the bounding box of the target node is less than _distMax, the matching is done.
		*  Theese bot and top points coordinates of the nodes are cumputed as a per centage of their respecting mesh bounding box.
		*
		* \todo Il serait peut etre bien de creer une methode dans la classe boundongbox pour comparer deux bounding box entre elles au lieu de le faire en vrac dans cette fonction.
		*
		*  \param _reference : Node taken as the reference for the computation.
		*  \param _refBBox : Bounding box of the reference's mesh.
		*  \param _target : Root of the tree containing the segments we want to match with the reference.
		*  \param _targetMeshBBox : Bounding box of the targets node's mesh.
		*  \param _distMax : Distance maximum to considerate two segments as matched.
		*
		*  \return (void)
		*/
		void getMatchBy_BoundingBoxBotX ( SegmentTree* _reference, BoundingBox _refMeshBBox, SegmentTree* _target, BoundingBox _targetMeshBBox, int _distMax);
		
		/*!
		*  \brief Creates a list containing all the node in the target matched by the reference node given in parameter according to a similarity on the bounding boxes.
		*
		*  Creates a list containing all the node in the target matched by the reference node given in parameter according to a similarity on the bounding boxes :
		*  If the difference between the x coordinate of the top point of the bounding box of the reference node and the top point of the bounding box of the target node is less than _distMax, the matching is done.
		*  Theese bot and top points coordinates of the nodes are cumputed as a per centage of their respecting mesh bounding box.
		*
		* \todo Il serait peut etre bien de creer une methode dans la classe boundongbox pour comparer deux bounding box entre elles au lieu de le faire en vrac dans cette fonction.
		*
		*  \param _reference : Node taken as the reference for the computation.
		*  \param _refBBox : Bounding box of the reference's mesh.
		*  \param _target : Root of the tree containing the segments we want to match with the reference.
		*  \param _targetMeshBBox : Bounding box of the targets node's mesh.
		*  \param _distMax : Distance maximum to considerate two segments as matched.
		*
		*  \return (void)
		*/
		void getMatchBy_BoundingBoxTopX ( SegmentTree* _reference, BoundingBox _refMeshBBox, SegmentTree* _target, BoundingBox _targetMeshBBox, int _distMax);
		
		/*!
		*  \brief Creates a list containing all the node in the target matched by the reference node given in parameter according to a similarity on the bounding boxes.Please see the getMatchBy_BoundingBoxBotX description.
		*/
		void getMatchBy_BoundingBoxBotY ( SegmentTree* _reference, BoundingBox _refMeshBBox, SegmentTree* _target, BoundingBox _targetMeshBBox, int _distMax);
		
		/*!
		*  \brief Creates a list containing all the node in the target matched by the reference node given in parameter according to a similarity on the bounding boxes.Please see the getMatchBy_BoundingBoxBotX description.
		*/
		void getMatchBy_BoundingBoxTopY ( SegmentTree* _reference, BoundingBox _refMeshBBox, SegmentTree* _target, BoundingBox _targetMeshBBox, int _distMax);
		
		/*!
		*  \brief Creates a list containing all the node in the target matched by the reference node given in parameter according to a similarity on the bounding boxes.Please see the getMatchBy_BoundingBoxBotX description.
		*/
		void getMatchBy_BoundingBoxBotZ ( SegmentTree* _reference, BoundingBox _refMeshBBox, SegmentTree* _target, BoundingBox _targetMeshBBox, int _distMax);
		
		/*!
		*  \brief Creates a list containing all the node in the target matched by the reference node given in parameter according to a similarity on the bounding boxes.Please see the getMatchBy_BoundingBoxBotX description.
		*/
		void getMatchBy_BoundingBoxTopZ ( SegmentTree* _reference, BoundingBox _refMeshBBox, SegmentTree* _target, BoundingBox _targetMeshBBox, int _distMax);
		
		/*!
		*  \brief Creates a list containing all the node in the target matched by the reference node given in parameter according to a similarity on the bounding boxes.
		*
		*  Creates a list containing all the node in the target matched by the reference node given in parameter according to a similarity on the bounding boxes :
		*  If the difference between the x coordinate of the top & bot point of the bounding box of the reference node and the top & bot point of the bounding box of the target node is less than _distMax, the matching is done.
		*  Theese bot and top points coordinates of the nodes are cumputed as a per centage of their respecting mesh bounding box.
		*
		* \todo Il serait peut etre bien de creer une methode dans la classe boundongbox pour comparer deux bounding box entre elles au lieu de le faire en vrac dans cette fonction.
		*
		*  \param _reference : Node taken as the reference for the computation.
		*  \param _refBBox : Bounding box of the reference's mesh.
		*  \param _target : Root of the tree containing the segments we want to match with the reference.
		*  \param _targetMeshBBox : Bounding box of the targets node's mesh.
		*  \param _distMax : Distance maximum to considerate two segments as matched.
		*
		*  \return (void)
		*/
		void getMatchBy_BoundingBoxX ( SegmentTree* _reference, BoundingBox _refMeshBBox, SegmentTree* _target, BoundingBox _targetMeshBBox, int _distMax);
		
		/*!
		*  \brief Creates a list containing all the node in the target matched by the reference node given in parameter according to a similarity on the bounding boxes.Please see the getMatchBy_BoundingBoxX description.
		*/
		void getMatchBy_BoundingBoxZ ( SegmentTree* _reference, BoundingBox _refMeshBBox, SegmentTree* _target, BoundingBox _targetMeshBBox, int _distMax);
		
		/*!
		*  \brief Creates a list containing all the node in the target matched by the reference node given in parameter according to a similarity on the bounding boxes.Please see the getMatchBy_BoundingBoxX description.
		*/
		void getMatchBy_BoundingBoxY ( SegmentTree* _reference, BoundingBox _refMeshBBox, SegmentTree* _target, BoundingBox _targetMeshBBox, int _distMax);
		
		/*!
		*  \brief Displays the list of nodes in a certain mode.
		*
		*  Displays the list of nodes in a certain mode.
		*
		*  \param _mode : Mode to display the list. Can be OWN_COLOR, OTHER_COLOR or MESH_COLOR.
		*  \param _r : Red component of the color to display. ONLY IF THE MODE IS "OTHER_COLOR". Set to 1 by default.
		*  \param _g : Green component of the color to display. ONLY IF THE MODE IS "OTHER_COLOR". Set to 0 by default.
		*  \param _b : Blue component of the color to display. ONLY IF THE MODE IS "OTHER_COLOR". Set to 0 by default.
		*
		*  \return (void)
		*/
		void display( int _mode = MESH_COLOR, double _r = 1, double _g = 0, double _b = 0 );
};

#endif // SEGMENTTREELIST_H
